﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Solidi
{
	/// <summary>
	/// Thread-safe
	/// </summary>
	/// <remarks>
	/// The thread safety of the children in the implemtation of this class is important
	/// as children created as factory dependencies (Func<>) might then be called on different threads.
	/// </remarks>
	sealed class DependencyObjectLifetime : IDependencyLifetime
	{
		private IList<object> _children = new List<object>();
		private IDependencyContainer _container;
		
		public DependencyObjectLifetime(IDependencyContainer container)
		{
			_container = container;
		}

		public IEnumerable<object> Children { get { return new ConcurrentEnumerable(_children, _children); } }

		public bool TryAcquire(object graphId, IDependencyContainer container, IDependency dependency, out object instance)
		{
			return Track(_container.Lifetime.TryAcquire(graphId, _container, dependency, out instance), instance);
		}

		public bool TryAcquire(IDependencyContainer container, IDependency dependency, out object instance)
		{
			return Track(_container.Lifetime.TryAcquire(_container, dependency, out instance), instance);
		}

		private bool Track(bool success, object instance)
		{
			if (success)
			{
				lock (_children)
				{
					_children.Add(instance);
				}

				return true;
			}
			else
			{
				return false;
			}
		}

		public bool TryDiscard(IDependencyContainer container, object instance)
		{
			return _container.Lifetime.TryDiscard(_container, instance);
		}

		public void DiscardAll(IDependencyContainer container, bool disposing)
		{
			_container.Lifetime.DiscardAll(_container, disposing);
		}
	}
}
